﻿
using System.Collections;
using System.Reflection;
using System.Xml;
using System.IO;
using System.Threading;
namespace Ecopsy.DataTier
{
    /// <summary>
    /// В зависимости от поодержки ISqlSugnature поведение Entity, EntityList  в части Load() Save() - меняется
    /// RW_Engine- стратегия - реализующее эти изменения.
    /// </summary>

    public abstract class RW_Engine
    {
        public virtual void Load()
        {
            throw new System.NotImplementedException();
        }

        public virtual void Save()
        {
            throw new System.NotImplementedException();
        }

    }

    public class RW_SingleEng : RW_Engine 
    {
        protected  EntitySingle _EntitySingle;
        public RW_SingleEng(EntitySingle EntitySingle) { _EntitySingle = EntitySingle; }
        public override  void Load()
        {
            try
            {
                ArrayList l = _EntitySingle.IEntityProperties;
                foreach (PropertyInfo inf in l)
                {
                    object v = inf.GetValue(_EntitySingle, null);
                    if (null == v) continue;
                    ((IEntity)v).Load();
                }
                
            }
            catch 
            {
                throw;
            }

        }
        public override  void Save()
        {
            try
            {
                ArrayList l = _EntitySingle.IEntityProperties; 
                foreach (PropertyInfo inf in l)
                {

                    object v = inf.GetValue(_EntitySingle, null);
                    if (null == v) continue;
                    
                        ((IEntity)v).Save();
                    
                }
            }
            catch
            {   
                throw;
            }
        }
    }

    public class SQL_RW_SingleEng : RW_SingleEng
    {
        public SQL_RW_SingleEng(EntitySingle _EntitySingle) : base(_EntitySingle) { }
        public override void  Save()
    {
        if (EntityState.Loaded != _EntitySingle.State)
        {
            SecuretyContext SC = new SecuretyContext("");
            SC = AppContext.GetSC(((EntitySingle)_EntitySingle).Def_SCName);
            ISqlSignature o = (ISqlSignature)_EntitySingle;
            SqlTools tls = new SqlTools(SC);
            string sp = _EntitySingle.State.Equals(EntityState.Deleted) ? o.DeleteProcedure : o.SaveProcedure;
            tls.ExecuteCommand_NonQuery(sp, _EntitySingle);
            base.Save();
            	
        }
        
    }

    
        public override void Load()
        {
            SecuretyContext SC = AppContext.GetSC(_EntitySingle.Def_SCName);
            try
            {   
                ISqlSignature o = (ISqlSignature)_EntitySingle;
                SqlTools tls = new SqlTools(SC);
                XmlReader r = tls.ReadXml(o.LoadProcedure, _EntitySingle);
                XmlDocument d = new XmlDocument();
                d.Load(r);
                _EntitySingle.ReadXml(d.FirstChild);

                base.Load();
            }
            finally
            {
                if(SC.Connection.State ==System.Data.ConnectionState.Open)  SC.Connection.Close(); 
            }
            
        }
    }

    public class RW_ListEng : RW_Engine
    {
        protected EntityList _EntityList;
        public RW_ListEng(EntityList EntityList) { _EntityList = EntityList; }
        public override void Load()
        {
            try
            {
                _EntityList.Reset();
                foreach (EntitySingle item in _EntityList)
                {
                    ((EntitySingle)item).Load();
                }
            }
            catch
            {
                throw;
            }

        }
        public override void Save()
        {
            try
            {
                if (0 == _EntityList.Count) return;
                _EntityList.Reset();
                foreach (EntitySingle item in _EntityList) ((EntitySingle)item).Save();                
            }
            catch
            {
                throw;
            }
        }
    }

    public class SQL_RW_ListEng : RW_ListEng
    {   
        public SQL_RW_ListEng(EntityList EntityList) : base(EntityList) { }

        public override void Load()
        {
            SecuretyContext SC = AppContext.GetSC(_EntityList.Def_SCName);
            try
            {                
                ISqlSignature o = (ISqlSignature)_EntityList;
                SqlTools tls = new SqlTools(SC);
                XmlReader r = tls.ReadXml(o.LoadProcedure, _EntityList);
                if (null == r) return;
                XmlDocument d = new XmlDocument();
                d.Load(r);
                if (0 == d.ChildNodes.Count) return;
                if (null == d.FirstChild) return;
                _EntityList.Clear();
                _EntityList.ReadXml(d.FirstChild);

                foreach (Entity item in _EntityList)
                        item.SetHash();
            }
            catch
            {
                throw;
            }
            finally
            {
                SC.Connection.Close();  
            }

            
        }
        
        
    }

    

    public class File_RW_SingleEng : RW_SingleEng 
    {    
        public File_RW_SingleEng(EntitySingle EntitySingle) :base(EntitySingle){}
        
        public override void Load()
        {
            FileStream fs = null;
            try
            {
                IFileSignature FileSign = (IFileSignature)_EntitySingle;

                fs = new FileStream(FileSign.Folder + FileSign.FileName, FileMode.Open);
                XmlTextReader r = new XmlTextReader(fs);
                XmlDocument d = new XmlDocument();
                d.Load(r);
                _EntitySingle.ReadXml(d.FirstChild);
            }
            catch
            {
                throw;
            }
            finally
            {
                if (null != fs) fs.Close();
            }
        }
       
        public override void Save()
        {
            if (EntityState.Loaded != _EntitySingle.State)
            {
                IFileSignature FileSign = (IFileSignature)_EntitySingle;

                FileStream fs = null;
                StreamWriter wr = null;

                base.Save();

                try
                {
                    fs = new FileStream(FileSign.Folder + FileSign.FileName, FileMode.OpenOrCreate);
                    string s = _EntitySingle.ToXml(true);
                    wr = new StreamWriter(fs);
                    wr.Write(s);

                }
                catch
                {
                    throw;
                }
                finally
                {
                    if (null != wr) wr.Close();
                    if (null != fs) fs.Close();

                }

            }            
        }
    }


}